
#ifndef _WIDGET_H_
#define _WIDGET_H_

#include <SDL/SDL.h>
#include "Object.h"
#include "movement.h"
#include "effect.h"

namespace animationagent {

enum WidgetEvent
{
    ON_MOVE_FINISH,
    ON_ANIM_FINISH,
    ON_FADEALPHA_FINISH
};

class Widget : public Object
{
public:
    Widget      *parent;
    Widget      *left_child;
    Widget      *next_brother;
    Widget      *prio_brother;

    //bool need_repaint();
    virtual void draw(SDL_Surface *screen);
    virtual void update();
    void set_visible(bool v);
    bool get_visible();
    void set_level(Sint16 val);
    Sint16 get_level();
    virtual void set_bgcolor(SDL_Color &c);
    virtual void set_fncolor(SDL_Color &c);
    void set_movement(Movement *m);
    void set_effect(Effect *e);
    SDL_Rect get_allocation();
    void set_allocation(Sint16 x, Sint16 y, Uint16 w, Uint16 h);
    void set_allocation(SDL_Rect rect);
    void set_allocation(Sint16 x, Sint16 y);
    Sint16 get_screen_x();
    Sint16 get_screen_y();
    Widget();
    virtual ~Widget();

    inline void wtree_add_brother_before(Widget *node);
    inline void wtree_add_brother_after(Widget *node);
    void wtree_add_child(Widget *child);
    void wtree_split_from_parent();
    void wtree_break_tree();
    static void wtree_levelorder_traversal(Widget *node,
        void (*callback)(Widget *node, void *param, void * param2),
        void *param, void *param2);
    static void wtree_postorder_traversal(Widget *node,
        void (*callback)(Widget *node, void *param, void * param2),
        void *param, void *param2);

protected:
    SDL_Surface *p_surface;     //only for display
    SDL_Color   bgcolor;        //background color
    SDL_Color   fncolor;        //front color
    SDL_Rect    allocation;     //parent coordinate x, y, and width, height
    Sint16      screen_x;       //screen coordinate x
    Sint16      screen_y;       //screen coordinate y
    Sint16      level;          //display order
    bool        visible;        //is visible?
    bool        dirty;          //is dirty?


private:
    Movement *movement;
    Effect   *effect;

    void init();
    //inline void set_location(Sint16 x, Sint16 y);
};


//void wtree_add_brother(Widget *base, Widget *brother);


//void wtree_remove_subtree_by_id(Widget *base, char *ID);




}

#endif
